#include "CxType.h"
#include "CxBuffer.h"


using namespace ImitateTansfer;

CxWriteBuffer::CxWriteBuffer():m_capacity(32)
{
}


CxWriteBuffer::CxWriteBuffer(size_t buffersize):m_capacity(buffersize)
{
}


CxWriteBuffer::~CxWriteBuffer()
{
    Clear();
}



void	CxWriteBuffer::Clear()
{
    {
        boost::mutex::scoped_lock lock(m_mu);

        if(Is_Empty())return ;
        else
        {
            for(BOOST_AUTO(i,m_buffer.begin());i!=m_buffer.end();++i)
                delete [] *i;

            m_buffer.clear();
            CX_ASSERT(!m_buffer.size());
        }
    }
}


CxPackage *	CxWriteBuffer::PopBuffer()
{
    CxPackage *tmp=NULL;

    try
    {
        {
            boost::mutex::scoped_lock lock(m_mu);

            while(Is_Empty())
            {
                m_readcond.wait(m_mu);
            }

            tmp=m_buffer.back();
            m_buffer.pop_back();

            m_writecond.notify_one();
        }
        return	tmp;
    }
    //Òì³£´¦ÀíÍË³ö

    catch(const boost::lock_error &e)
    {
        throw ;
    }
    catch(const boost::thread_interrupted &e)
    {
        throw ;
    }
}



void	CxWriteBuffer::PushBuffer(CxPackage	*buffer)
{

    try
    {
        {
            boost::mutex::scoped_lock lock(m_mu);

            //bufferÂúµÈ´ý
            while(Is_Full())
            {
                m_writecond.wait(m_mu);
            }
            m_buffer.push_front(buffer);

            //ÌáÐÑbufferµ÷ÓÃÕßbufferÒÑ¿ÉÒÔ´æ´¢
            m_readcond.notify_one();
        }
    }


    //threadÒì³£´¦Àí£¬ÍË³ö
    catch(boost::thread_interrupted &)
    {
        throw ;
    }
}
